﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace DemoKAMEHAMEHA
{
    using Microsoft.Research.Kinect;
    using Microsoft.Research.Kinect.Nui;
    using KINECTUtility;
    using BombPart;

    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        Runtime nuiRuntime;
        AreaChecker myAreaChecker;
        RuleChecker myRuleChecker;

        double unitWidth = 40;
        double unitHeight = 40;
        double windowHight = 480;
        double windowWidth = 640;
        double offset;
        
        Rectangle markRect = new Rectangle();

        public MainWindow()
        {
            InitializeComponent();

            offset = (1280 - windowWidth) / 2;


            myAreaChecker = new AreaChecker(windowWidth, windowHight, unitWidth, unitHeight);
            myAreaChecker.RegistCheckJointID(JointID.HandLeft);
      //      myAreaChecker.RegistCheckJointID(JointID.HandRight);

            myRuleChecker = new RuleChecker(myAreaChecker);
            myRuleChecker.AddRule(6, 10, RuleDefinition.ActionMode.Hold);
            myRuleChecker.AddRule(7, 10, RuleDefinition.ActionMode.Occupied);
            myRuleChecker.AddRule(6, 10, RuleDefinition.ActionMode.Through);

            markRect.Width = unitWidth;
            markRect.Height = unitHeight;
            markRect.Fill = new SolidColorBrush(Colors.Azure);
       //     markRect.Opacity = 0.5;

            Canvas.SetTop(markRect, 3 * unitHeight);
            Canvas.SetLeft(markRect, 5 * unitWidth+offset);
            canvasAR.Children.Add(markRect);

            nuiRuntime = new Runtime();
            nuiRuntime.Initialize(RuntimeOptions.UseColor | RuntimeOptions.UseSkeletalTracking| RuntimeOptions.UseDepthAndPlayerIndex);
            nuiRuntime.VideoStream.Open(ImageStreamType.Video, 2, ImageResolution.Resolution640x480, ImageType.Color);
            
            nuiRuntime.VideoFrameReady += new EventHandler<ImageFrameReadyEventArgs>(nuiRuntime_VideoFrameReady);
            nuiRuntime.SkeletonFrameReady += new EventHandler<SkeletonFrameReadyEventArgs>(nuiRuntime_SkeletonFrameReady);

            myRuleChecker.RuleProgressed += new RuleChecker.AreaRuleCheckerProgressEventHandler(myRuleChecker_RuleProgressed);
            myRuleChecker.RuleCompleted += new RuleChecker.AreaRuleCheckerPerfectEventHandler(myRuleChecker_RuleCompleted);

            myAreaChecker.AreaMoved += new AreaChecker.AreaCheckerUpdateEventHandler(myAreaChecker_AreaMoved);
            myAreaChecker.AreaHold += new AreaChecker.AreaCheckerHoldEventHandler(myAreaChecker_AreaHold);

            myRuleChecker.StartTracing(JointID.HandLeft);
        }

        void myAreaChecker_AreaHold(AreaCheckerHoldEventArgs e)
        {
            if (e.HoldJoint == JointID.HandLeft)
            {
                tbHold.Text = String.Format("Hold:X={0},Y={1}", e.HoldIndexHorizontal, e.HoldIndexVertical);
                canvasAR.Children.Clear();
                var bomb = new Bomb();
                bomb.MovingMode = MovingMode.None;
                Canvas.SetTop(bomb, e.HoldIndexVertical * unitHeight);
                Canvas.SetLeft(bomb, e.HoldIndexHorizontal * unitWidth + offset);
                canvasAR.Children.Add(bomb);
                bomb.Fire();
            }
        }

        private DateTime lastMovedTime = DateTime.Now;
        void myAreaChecker_AreaMoved(AreaCheckerUpdateEventArgs e)
        {
            DateTime currentTime = DateTime.Now;
            if (e.MovedJoint == JointID.HandLeft)
            {
                tbMove.Text = String.Format("Move:X={0},Y={1}", e.CurrentIndexHorizontal, e.CurrentIndexVertical);
                if ((currentTime - lastMovedTime) < TimeSpan.FromMilliseconds(500) && e.MoveToLeft)
                {
                    canvasAR.Children.Clear();
                    var bomb = new Bomb();
                    bomb.MovingMode = MovingMode.Left;
                    if (e.MoveToRight)
                    {
                        bomb.MovingMode = MovingMode.Right;
                    }
                    bomb.MovingFactor = 400;
                    Canvas.SetTop(bomb, e.CurrentIndexVertical * unitHeight);
                    Canvas.SetLeft(bomb, e.CurrentIndexHorizontal * unitWidth + offset);
                    canvasAR.Children.Add(bomb);
                    bomb.Fire();
                }
            }
            lastMovedTime = currentTime;
        }

        void myRuleChecker_RuleProgressed(RuleChecker source, int currentStep)
        {
            switch (currentStep)
            {
                case 0:
                    markRect.Fill = new SolidColorBrush(Colors.Blue);
                    break;
                case 1:
                    markRect.Fill = new SolidColorBrush(Colors.Yellow);
                    break;
            }
        }

        void myRuleChecker_RuleCompleted(RuleChecker source)
        {
            canvasAR.Children.Clear();
            var bomb = new Bomb();
            Canvas.SetTop(bomb, 10 * unitHeight + unitHeight / 2);
            Canvas.SetLeft(bomb, 10 * unitWidth + unitWidth / 2+offset);
            canvasAR.Children.Add(bomb);
            bomb.MovingMode = MovingMode.Left;
            bomb.MovingFactor = 200;
            bomb.Fire();
        }

        void nuiRuntime_SkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
        {
            SkeletonFrame frame = e.SkeletonFrame;
            foreach (var skelton in frame.Skeletons)
            {
                if (skelton.TrackingState == SkeletonTrackingState.Tracked)
                {
                    myAreaChecker.BeginCheck();
                    float hlx = skelton.Joints[JointID.HandLeft].Position.X;
                    float hly = skelton.Joints[JointID.HandLeft].Position.Y;

                    //              float hrx = skelton.Joints[JointID.HandRight].Position.X;
                    //            float hry = skelton.Joints[JointID.HandRight].Position.Y;

                    myAreaChecker.IsIncludePoint(hlx, hly, JointID.HandLeft);
                    //          myAreaChecker.IsIncludePoint(hrx, hry, JointID.HandRight);

                    myAreaChecker.EndCheck();
                    break;
                }
            }
        }

        void nuiRuntime_VideoFrameReady(object sender, ImageFrameReadyEventArgs e)
        {
            PlanarImage image = e.ImageFrame.Image;
            imageViewer.Source=BitmapImage.Create(image.Width,image.Height
                , 96, 96, PixelFormats.Bgr32, null, image.Bits, image.Width * image.BytesPerPixel);
        }
    }
}
